package com.qqq.adminservice.config.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qqq.adminapi.config.domain.dto.ArgumentAddReqDTO;
import com.qqq.adminapi.config.domain.dto.ArgumentDTO;
import com.qqq.adminapi.config.domain.dto.ArgumentEditReqDTO;
import com.qqq.adminapi.config.domain.dto.ArgumentListReqDTO;
import com.qqq.adminapi.config.domain.vo.ArgumentVO;
import com.qqq.adminservice.config.domain.entity.SysArgument;
import com.qqq.adminservice.config.mapper.SysArgumentMapper;
import com.qqq.adminservice.config.service.ISysArgumentService;
import com.qqq.commondomain.domain.vo.BasePageVO;
import com.qqq.commondomain.exception.ServiceException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 参数服务实现类
 */
@Service
@Slf4j
public class SysArgumentServiceImpl implements ISysArgumentService {

    @Resource
    private SysArgumentMapper sysArgumentMapper;

    /**
     * 新增参数
     * @param argumentAddReqDTO 新增参数请求DTO
     * @return Long
     */
    @Override
    public Long add(ArgumentAddReqDTO argumentAddReqDTO) {
        SysArgument sysArgument = sysArgumentMapper.selectOne(new LambdaQueryWrapper<SysArgument>()
                .eq(SysArgument::getName, argumentAddReqDTO.getName())
                .or()
                .eq(SysArgument::getConfigKey, argumentAddReqDTO.getConfigKey()));
        // 尽量减少使用select *
        // 加的时候，名和键都不能重复
        if (sysArgument != null) {
            throw new ServiceException("参数已经存在");
        }
        sysArgument = new SysArgument();
        sysArgument.setName(argumentAddReqDTO.getName());
        sysArgument.setValue(argumentAddReqDTO.getValue());
        sysArgument.setConfigKey(argumentAddReqDTO.getConfigKey());
        if (StringUtils.isNotBlank(argumentAddReqDTO.getRemark())) {
            sysArgument.setRemark(argumentAddReqDTO.getRemark());
        }
        sysArgumentMapper.insert(sysArgument);
        return sysArgument.getId();
    }

    /**
     * 参数列表
     * @param argumentListReqDTO 查看参数DTO
     * @return BasePageVO
     */
    @Override
    public BasePageVO<ArgumentVO> list(ArgumentListReqDTO argumentListReqDTO)
    {
        BasePageVO<ArgumentVO> result = new BasePageVO<>();
        // 执行查询逻辑
        LambdaQueryWrapper<SysArgument> queryWrapper = new
                LambdaQueryWrapper<>();
        // 业务主键不为空
        if (StringUtils.isNotBlank(argumentListReqDTO.getConfigKey())) {
            queryWrapper.eq(SysArgument::getConfigKey, argumentListReqDTO.getConfigKey());
        }
        // 参数名称不为空
        if (StringUtils.isNotBlank(argumentListReqDTO.getName())) {
            queryWrapper.likeRight(SysArgument::getName, argumentListReqDTO.getName());
        }
        // 进行分页查询
        Page<SysArgument> page = sysArgumentMapper.selectPage(new Page<>
                (argumentListReqDTO.getPageNo().longValue(),
                        argumentListReqDTO.getPageSize().longValue()), queryWrapper);
        result.setTotals(Integer.parseInt(String.valueOf(page.getTotal())));
        result.setTotalPages(Integer.parseInt(String.valueOf(page.getPages())));
        List<ArgumentVO> list = new ArrayList<>();
        for (SysArgument sysArgument : page.getRecords()) {
            ArgumentVO argumentVo = new ArgumentVO();
            BeanUtils.copyProperties(sysArgument, argumentVo);
            list.add(argumentVo);
        }
        result.setList(list);
        return result;
    }

    /**
     * 参数列表
     * @param argumentEditReqDTO 查看参数DTO
     * @return BasePageVO
     */
    @Override
    public Long edit(ArgumentEditReqDTO argumentEditReqDTO) {
        SysArgument sysArgument = sysArgumentMapper.selectOne(new
                LambdaQueryWrapper<SysArgument>().eq(SysArgument::getConfigKey,
                argumentEditReqDTO.getConfigKey()));
        if (sysArgument == null) {
            throw new ServiceException("参数不存在");
        }
        // 作唯一性参数名称校验
        if(sysArgumentMapper.selectOne(new LambdaQueryWrapper<SysArgument>()
                .eq(SysArgument::getName,argumentEditReqDTO.getName())
                .ne(SysArgument::getConfigKey,argumentEditReqDTO.getConfigKey()))
        != null){
            throw new ServiceException("参数名称存在冲突");
        }
        sysArgument.setName(argumentEditReqDTO.getName());
        sysArgument.setValue(argumentEditReqDTO.getValue());
        sysArgument.setRemark(argumentEditReqDTO.getRemark());
        sysArgumentMapper.updateById(sysArgument);
        return sysArgument.getId();
    }

    /**
     * 根据参数查询参数对象
     * @param configKey 参数键
     * @return 参数对象
     */
    @Override
    public ArgumentDTO getByConfigKey(String configKey) {
        /*// 1 根据参数业务主键查询参数对象
        SysArgument sysArgument = sysArgumentMapper.selectOne(new LambdaQueryWrapper<SysArgument>()
                .eq(SysArgument::getConfigKey, configKey));
        // 2 做对象转换
        if (sysArgument != null) {
            ArgumentDTO argumentDTO = new ArgumentDTO();
            BeanUtils.copyProperties(sysArgument, argumentDTO);
            return argumentDTO;
        }*/
        List<ArgumentDTO> list = getByConfigKeys(new ArrayList<>() {
            {add(configKey);}});
        return list.isEmpty() == true ? null : list.get(0);
    }

    /**
     * 根据多个参数键获取多个参数对象
     * @param configKeys 参数键
     * @return 参数对象
     */
    @Override
    public List<ArgumentDTO> getByConfigKeys(List<String> configKeys) {
        if (configKeys.isEmpty()) {
            return null;
        }
        List<SysArgument> result = sysArgumentMapper.selectList(new LambdaQueryWrapper<SysArgument>()
                .in(SysArgument::getConfigKey, configKeys));
        List<ArgumentDTO> list = new ArrayList<>();
        for (SysArgument sysArgument : result) {
            ArgumentDTO argumentDTO = new ArgumentDTO();
            BeanUtils.copyProperties(sysArgument, argumentDTO);
            list.add(argumentDTO);
        }
        return list;
    }
}
